import base64
import datetime
import hashlib
import hmac
import json
import random
import requests
import time
import urllib
import math

from hashlib import sha256

import redis
from django.db.models import Q, F
# 悲观锁
from django.db import transaction
from django.core.mail import send_mail  # 用来发送用
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, HttpRequest
from django.contrib.auth.backends import ModelBackend  # 验证基类
from rest_framework_jwt.settings import api_settings
from rest_framework.views import APIView
from django.views import View
from django.contrib.auth import authenticate
from django.http import HttpResponse
from django.shortcuts import render

from rest_framework_jwt.utils import jwt_decode_handler
from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, BasePermission
from rest_framework.response import Response



# 阿里云短信
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest

from .models import *
from .ser import *


# 导入秘钥
from admin_keys.config import AK, SK, token_SK

# Create your views here.


# 获取七牛云token
# 七牛云密钥接口
from qiniu import Auth


class QiNiu(APIView):
    def get(self, request):
        # 声明密钥对象
        q = Auth(AK, SK)
        # 生成令牌
        token = q.upload_token('missty520')
        return Response({'up_token': token})


"""
工具方法
"""
def resultLog(order):
    start_location = order.start_location
    print(start_location)
    end_location = order.end_location
    start_lat, start_lon = float(start_location.split(',')[1]), float(start_location.split(',')[0])
    end_lat, end_lon = float(end_location.split(',')[1]), float(end_location.split(',')[0])
    distance = get_distance_hav(start_lat, start_lon, end_lat, end_lon)
    type_object = order.type
    type_data = TypeSer(type_object, many=True).data
    period = float(type_data[0].get('period'))
    # 设每小时100公里
    # 每个周期行进的距离：
    per = period / 60 * 100

    # 周期数
    current = int(math.floor(distance / per))

    # 高温
    high_temp = float(order.high_temp)
    # 低温
    low_temp = float(order.low_temp)

    mu = (high_temp + low_temp) / 2

    sigma = 1 + random.random()

    # 超温次数
    j = 0
    # 记录结果
    record = []
    now = order.start_time
    delta = datetime.timedelta(seconds=period * 60)
    for i in range(current):
        rec = {}
        # 时间
        n_days = now + (delta * i)
        rec['time'] = n_days.strftime('%Y-%m-%d %H:%M:%S')
        # 正态分布随机温度
        temp = random.normalvariate(mu=mu, sigma=sigma)
        rec['temp'] = temp
        if temp < low_temp or temp > high_temp:
            j += 1
            rec['judge'] = '超温'
        else:
            rec['judge'] = '正常'
        rec['lon'] = start_lon + (((start_lon - end_lon) / current) * i)
        rec['lat'] = start_lat + (((start_lat - end_lat) / current) * i)
        record.append(rec)
    print(j)
    return record, j, (j * period)


# 计算两经纬度之间的距离
from math import sin, asin, cos, radians, fabs, sqrt
EARTH_RADIUS = 6371  # 地球平均半径，6371km
def hav(theta):
    s = sin(theta / 2)
    return s * s
def get_distance_hav(lat0, lng0, lat1, lng1):
    "用haversine公式计算球面两点间的距离。"
    # 经纬度转换成弧度
    lat0 = radians(lat0)
    lat1 = radians(lat1)
    lng0 = radians(lng0)
    lng1 = radians(lng1)
    dlng = fabs(lng0 - lng1)
    dlat = fabs(lat0 - lat1)
    h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)
    distance = 2 * EARTH_RADIUS * asin(sqrt(h))
    return distance
# 计算两经纬度之间的距离
def distance(start_location, end_location):
    lon1, lat1 = float(start_location.split(',')[1]), float(start_location.split(',')[0])
    lon2, lat2 = float(end_location.split(',')[1]), float(end_location.split(',')[0])
    # lon1, lat1 = (22.599578, 113.973129)  # 深圳野生动物园(起点）
    # lon2, lat2 = (22.6986848, 114.3311032)  # 深圳坪山站 (百度地图测距：38.3km)
    d2 = get_distance_hav(lon1, lat1, lon2, lat2)
    return d2

# 获取坐标间距
#定义点的函数
class Point:
    def __init__(self,x=0,y=0):
        self.x=x
        self.y=y
    def getx(self):
        return self.x
    def gety(self):
        return self.y
#定义直线函数
class Getlen:
    def __init__(self,p1,p2):
        self.x=p1.getx()-p2.getx()
        self.y=p1.gety()-p2.gety()
        #用math.sqrt（）求平方根
        self.len= math.sqrt((self.x**2)+(self.y**2))
    #定义得到直线长度的函数
    def getlen(self):
        return self.len
# 获取坐标间距
def locational(location_list):
#设置点p1的坐标为（0,0）
    print(location_list[0].split(','))
    p1=Point(float(location_list[0].split(',')[0]),float(location_list[0].split(',')[1]))
    #设置点p2的坐标为（3,4）
    p2=Point(float(location_list[1].split(',')[0]),float(location_list[1].split(',')[1]))
    l=Getlen(p1,p2)
#获取两点之间直线的长度
    return int(7 - l.getlen() // 6)

# 权限认证方法
# 由前端传过来需要认证的权限和token，后端查询数据库进行判断，如果有该权限，返回true，没有返回false
# 获取权限
def getRights(request):
    uid = getID(request)
    character = User.objects.get(id=uid).character
    # print(office)
    # 获取权限，如果没有全局访问，则获取单个公司信息，否则获取所有公司信息
    # 序列化
    c_data = CharacterSer(character, many=True).data
    right_set = set()
    for c in c_data:
        for r in c.get('right'):
            right_set.add(r.get('id'))
    return right_set

# 从request里获取用户id
def getID(request):
    return jwt_decode_handler(request.META.get('HTTP_AUTHORIZATION')).get('user_id')

# 参数错误
def paramsError(res):
    res['code'] = 403
    res['message'] = '参数错误'
    return res

# 根据request获取公司dict
def getOffice(request):
    return OfficeSer(User.objects.get(id=getID(request)).office).data
